#pragma once

#ifndef __GLF_DEBUGGER_ALLOCATOR_H__
#define __GLF_DEBUGGER_ALLOCATOR_H__

#include <new>
#include <cstddef>
#include <memory>
#include <string>
#include <stdlib.h>

namespace glf
{
namespace debugger
{
	void*	Alloc(size_t cnt);
	void	Free(void* ptr);

template <typename T>
class DebuggerAllocator
{
public:

	// STL allocator compliance defs

	typedef size_t size_type;
	typedef std::ptrdiff_t difference_type;
	typedef T* pointer;
	typedef const T* const_pointer;
	typedef T& reference;
	typedef const T& const_reference;
	typedef T value_type;

	template <typename T1>
	struct rebind
	{
		typedef DebuggerAllocator<T1> other;
	};

	DebuggerAllocator()
	{
	}

	template <typename T2>
	DebuggerAllocator(const DebuggerAllocator<T2>& /*other*/)
	{
	}

	pointer address(reference r) const
	{
		return &r;
	}

	const_pointer address(const_reference r) const
	{
		return &r;
	}

	//! Allocate memory for an array of objects
	T* allocate(size_t cnt, const void* hint = 0)
	{
		return (T*)Alloc(cnt* sizeof(T));
	}

	size_type max_size() const
	{
		return size_type(-1) / sizeof(T);
	}

	//! Deallocate memory for an array of objects
	void deallocate(T* ptr, size_type n = 0)
	{
		Free(ptr);
	}

	//! Construct an element
	void construct(T* ptr, const T& e)
	{
		//placement_new ((void*)ptr) T(e);
		new ((void*)ptr) T(e);
	}

	//! Synonym for destruct (for STL compliance).
	void destroy(T* ptr)
	{
		ptr->~T();
	}

	// Below operators are required by some STL implementations

	bool operator == (const DebuggerAllocator& /*rhs*/) const
	{
		return true;
	}

	bool operator != (const DebuggerAllocator& /*rhs*/) const
	{
		return false;
	}

protected:


}; // end class DebuggerAllocator<T>

typedef std::basic_string< char, std::char_traits<char>, DebuggerAllocator<char> > stringdbg;

} // end namespace debugger
} // end namespace glf

#endif
